package edu.pw.treegrid.client.report.model;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RestDataSource;
import com.smartgwt.client.data.fields.DataSourceBooleanField;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceFloatField;
import com.smartgwt.client.data.fields.DataSourceImageField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceLinkField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.widgets.Canvas;

import edu.pw.treegrid.client.report.events.HierachyChangeListener;
import edu.pw.treegrid.shared.Configuration;
import edu.pw.treegrid.shared.ReportColumnCategory;
import edu.pw.treegrid.shared.ReportColumnDescription;
import edu.pw.treegrid.shared.ReportColumnType;

public class ReportDataSource extends RestDataSource {
	private String reportId;
	private String hierarchy = "";
	private Map<String, ReportColumnDescriptionClient> nameToColumn;
	private Map<ReportColumnDescriptionClient, DataSourceField> columnToField;
	private List<HierachyChangeListener> hierarchyChangeListeners = new LinkedList<HierachyChangeListener>();
	
	public void addHierarchyChangeListener(HierachyChangeListener listener) {
		hierarchyChangeListeners.add(listener);
	}
	
	private void notifyListeners(Collection<ReportColumnDescriptionClient> columns) {
		for(HierachyChangeListener l : hierarchyChangeListeners) {
			l.onHierarchyChanged(columns);
		}
	}
	
	public void setHierarchy(Record[] records) {
		hierarchy = "";
		
		for(ReportColumnDescriptionClient c : columnToField.keySet()) {
			if(c.getCategory() == ReportColumnCategory.HIERARCHY_NOT_VISIBLE) {
				c.setCategory(ReportColumnCategory.CANDIDATE_NOT_VISIBLE);
			}
			if(c.getCategory() == ReportColumnCategory.HIERARCHY) {
				c.setCategory(ReportColumnCategory.CANDITATE);
			}
		}
		
		for(Record r : records) {
			ReportColumnDescription c = nameToColumn.get(r.getAttribute(ReportColumnDescription.NAME));
			hierarchy += r.getAttribute(ReportColumnDescription.NAME);
			hierarchy += ";";
			r.setAttribute(ReportColumnDescription.FOLDER_COLUMN, true);			
			if(c.getCategory() == ReportColumnCategory.CANDIDATE_NOT_VISIBLE) {
				c.setCategory(ReportColumnCategory.HIERARCHY_NOT_VISIBLE);
			}
			else if(c.getCategory() == ReportColumnCategory.CANDITATE) {
				c.setCategory(ReportColumnCategory.HIERARCHY);
			}
		}
		
		notifyListeners(columnToField.keySet());
	}
	
	public ReportDataSource(String reportId) {
		this.reportId = reportId;
		setID("ReportDataSource-" + reportId);
		setTitleField(ReportColumnDescription.NAME_COLUMN);
		this.setFetchDataURL(Configuration.PREFIX + Configuration.DATA_URL);
	}

	public void setColumns(List<ReportColumnDescriptionClient> columns) {
		this.nameToColumn = new HashMap<String, ReportColumnDescriptionClient>();
		this.columnToField = new HashMap<ReportColumnDescriptionClient, DataSourceField>();
		
		
		for(ReportColumnDescriptionClient rcd : columns) {
			this.nameToColumn.put(rcd.getName(), rcd);
			DataSourceField field = newField(rcd);
			field.setName(rcd.getName());
			field.setTitle(rcd.getTitle());
			field.setHidden(!rcd.getCategory().isVisibleAsReportFilter());
			field.setAttribute(ReportColumnDescription.WIDTH, rcd.getWidth());
			this.columnToField.put(rcd, field);
			addField(field);			
		}
		
		getField(ReportColumnDescription.PATH_COLUMN).setPrimaryKey(true);
		
		getField(ReportColumnDescription.PARENT_PATH_COLUMN).setRequired(true);
		getField(ReportColumnDescription.PARENT_PATH_COLUMN).setForeignKey(id + "." + ReportColumnDescription.PATH_COLUMN);
		getField(ReportColumnDescription.PARENT_PATH_COLUMN).setRootValue("null");
		//to moze zadziala:
		//getField(ReportColumnDescription.NAME_COLUMN).setAttribute("frozen", true);
		//getField(ReportColumnDescription.NAME_COLUMN).setAttribute("freeze", true);
	}
	
	private DataSourceField newField(ReportColumnDescriptionClient rcd) {
		switch(rcd.getType()) {
			case DATE: return new DataSourceDateField();
			case BOOLEAN: return new DataSourceBooleanField();
			case TEXT: return new DataSourceTextField();
			case INTEGER: return new DataSourceIntegerField();
			case FLOAT: return new DataSourceFloatField();
			case IMG:  return new DataSourceImageField();
			case LINK:
				DataSourceField f = new DataSourceLinkField();
				f.setAttribute("linkText", Canvas.imgHTML(rcd.getImageSrc(), 16, 16, "info", "align=center", null));
				return f;
		}
		
		return null;
	}
	
	
	@Override
    protected Object transformRequest(DSRequest dsRequest) {
		Map<String, String> params = new HashMap<String, String>();
		params.put(Configuration.REPORT_ID_PARAM, reportId);
		params.put(Configuration.HIERARCHY_PARAM, hierarchy);
		dsRequest.setParams(params);
        return super.transformRequest(dsRequest);
    }
}
